#include "iniparser.h"

inline std::string &IniParser::ltrim(std::string &s)
{
    std::string::iterator pos = find_if(s.begin(),s.end(),std::not1(std::ptr_fun(isspace)));
    s.erase(s.begin(),pos);
    return s;
}

inline std::string &IniParser::rtrim(std::string &s)
{
    std::string::reverse_iterator pos = find_if(s.rbegin(),s.rend(),std::not1(std::ptr_fun(isspace)));
    s.erase(pos.base(),s.end());
    return s;
}

inline std::string &IniParser::trim(std::string &s)
{
    return ltrim(rtrim(s));
}

IniParser::IniParser(const std::string& file)
{
    std::fstream ini(file.data(),std::fstream::in);
    if(ini.good()){
	char section[1024] = {0};
	size_t left_bracket;
	size_t right_bracket;

	while(ini.getline(section,1024))
	{
	    std::string strSec(section);
	    //std::cout << strSec << std::endl;
	    left_bracket = strSec.find('[');
	    right_bracket = strSec.find(']');

	    if(strSec.length()
		&& left_bracket != std::string::npos
		&& right_bracket != std::string::npos
		&& right_bracket > left_bracket + 1)
	    {
		strSec = strSec.substr(left_bracket+1,right_bracket - left_bracket - 1);
		trim(strSec);

		char expression[1024] = {0};
		while(ini.getline(expression,1024)){
		    std::string strExp(expression);
		    if(strExp.length() <= 0)
			continue;

		    if(strExp.find('[') != std::string::npos
			&& strExp.find(']') != std::string::npos
			&& strExp.find(']') > strExp.find('[')) //got section
		    {
			std::streamoff off = (int)(-1 * (strExp.length() + 1));
			ini.seekp(off,std::ios::cur);			
			break;
		    }

		    //std::cout << strExp << std::endl;

		    size_t pos = strExp.find('=');
		    if(pos != std::string::npos){
			std::string key = strExp.substr(0,pos);
			std::string value = strExp.substr(pos+1);

			trim(key);
			trim(value);

			if(key.length() && value.length()){
			    std::map<std::string,std::string> &section_map = _content[strSec];
			    section_map.insert(std::map<std::string,std::string>::value_type(key,value));
			    //std::cout << "[" << strSec << "]" << key << "=>" << value <<std::endl;
			}
		    }
		}  //end while expression
		memset(expression,0,1024);
	    }
	    memset(section,0,1024);
	}   //end while section
    }
}

std::string IniParser::get(const std::string &section,const std::string &key)
{
    std::string value = "";
    if(_content.size()){
	MMAPIter iter = _content.find(section);
	if(iter != _content.end()){
	    std::map<std::string,std::string> &section_map = iter->second;
	    std::map<std::string,std::string>::iterator it = section_map.find(key);
	    if(it != section_map.end())
		return it->second;
	}
    }
    return value;
}
